package com.luych.toolbox.automation.service.core.executor;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.luych.toolbox.automation.service.constant.Constant;
import com.luych.toolbox.automation.service.core.connection.SqlConnection;
import com.mysql.cj.jdbc.Driver;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;

public class SqlExecutor implements TaskExecutor<SqlConnection> {

    private final String sql;

    public SqlExecutor(String sql) {
        this.sql = sql;
    }

    @Override
    public String execute(SqlConnection target, String... args) {
        String url;
        switch (target.getType()) {
            case MYSQL: {
                url = String.format("jdbc:mysql://%s:%d/%s?allowMultiQueries=true", target.getHost(), target.getPort(), target.getDb());
                break;
            }
            case DM: {
                url = String.format("jdbc:dm://%s:%d/%s", target.getHost(), target.getPort(), target.getDb());
                break;
            }
            default: throw new UnsupportedOperationException();
        }
        MysqlDataSource dataSource = DataSourceBuilder.create()
                .type(MysqlDataSource.class)
                .driverClassName(Driver.class.getName())
                .url(url).username(target.getUser()).password(target.getPass())
                .build();
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        if (sql.toUpperCase().startsWith("SELECT")
                || sql.toUpperCase().startsWith("SHOW")
                || sql.toUpperCase().startsWith("DESC")
                || sql.toUpperCase().startsWith("EXPLAIN")
                || sql.toUpperCase().startsWith("WITH")
        ) {
            List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, (Object[]) args);
            try {
                return new ObjectMapper().writeValueAsString(list);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(Constant.EXCEPTION_STDOUT_FORMAT);
            }
        } else {
            jdbcTemplate.update(sql, (Object[]) args);
            return "";
        }
    }
}
